//
//  PKNetworManager.swift
//  GoAbroad
//
//  Created by Pink Snow on 2025/5/7.
//

import Moya
import RxSwift
//import Moya_ObjectMapper
import ObjectMapper
import Alamofire

struct AuthPlugin: PluginType {
    func prepare(_ request: URLRequest, target: TargetType) -> URLRequest {
        var req = request
        if let token = TokenManager.shared.token {
            req.addValue(token, forHTTPHeaderField: "Authorization")
        }
        if let appId = TokenManager.shared.appid {
            req.addValue(appId, forHTTPHeaderField: "appid")
        }
        return req
    }
}

private let timeoutSession: Session = {
    let configuration = URLSessionConfiguration.default
    configuration.timeoutIntervalForRequest = 10 // 设置为 10 秒
    configuration.timeoutIntervalForResource = 10
    return Session(configuration: configuration)
}()



class NetworkManager {
    static let shared = NetworkManager()
    
    let provider = MoyaProvider<APIService>(session:timeoutSession)
    let authprovider = MoyaProvider<APIService> (session: timeoutSession, plugins: [AuthPlugin()])
    
    private init() {}
    
    func requestAuthObject<T: Mappable>(_ target: APIService, type: T.Type, using provider: MoyaProvider<APIService>? = nil) -> Observable<T> {
        let usedProvider = provider ?? self.provider
        
        return usedProvider.rx.request(target)
            .flatMap { response -> Single<Response> in
                if response.statusCode == 401, usedProvider === self.authprovider {
                    return self.refreshToken(TokenManager.shared.logintype).flatMap { _ in
                        return self.authprovider.rx.request(target)
                    }
                }
                
                return .just(response)
            }
            .filterSuccessfulStatusCodes()
            .mapObject(BaseResponse<T>.self)
            .asObservable()
            .flatMap { response -> Observable<T> in
                if response.isSuccess, let data = response.data {
                    return .just(data)
                } else {
                    let error = NSError(domain: "APIError", code: response.code ?? -1, userInfo: [NSLocalizedDescriptionKey: response.message ?? "Unknown error"])
                    return .error(error)
                }
            }
    }
    
    //    func requestAuthArrayObject<T: Mappable>(_ target: APIService, type: T.Type, using provider: MoyaProvider<APIService>? = nil) -> Observable<[T]> {
    //        let usedProvider = provider ?? self.provider
    //
    //        return usedProvider.rx.request(target)
    //            .flatMap { response -> Single<Response> in
    //                if response.statusCode == 401, usedProvider === self.authprovider {
    //                    return self.refreshToken().flatMap { _ in
    //                        return self.authprovider.rx.request(target)
    //                    }
    //                }
    //
    //                return .just(response)
    //            }
    //            .filterSuccessfulStatusCodes()
    //            .mapArray(BaseArrayResponse<T>.self)
    //            .asObservable()
    //            .flatMap { response -> Observable<[T]> in
    //                if response.isSuccess, let data = response.data {
    //                    return .just(data)
    //                } else {
    //                    let error = NSError(domain: "APIError", code: response.code ?? -1, userInfo: [NSLocalizedDescriptionKey: response.message ?? "Unknown error"])
    //                    return .error(error)
    //                }
    //            }
    //    }
    func requestAuthArray<T: Mappable>(_ target: APIService, type: T.Type, using provider: MoyaProvider<APIService>? = nil) -> Observable<[T]> {
        let usedProvider = provider ?? self.provider
        
        return usedProvider.rx.request(target)
            .flatMap { response -> Single<Response> in
                if response.statusCode == 401, usedProvider === self.authprovider {
                    return self.refreshToken(TokenManager.shared.logintype).flatMap { _ in
                        return self.authprovider.rx.request(target)
                    }
                }
                
                return .just(response)
            }
            .filterSuccessfulStatusCodes()
            .mapObject(BaseArrayResponse<T>.self)
            .asObservable()
            .flatMap { response -> Observable<[T]> in
                if response.isSuccess, let data = response.data {
                    return .just(data)
                } else {
                    let error = NSError(domain: "APIError", code: response.code ?? -1, userInfo: [NSLocalizedDescriptionKey: response.message ?? "Unknown error"])
                    return .error(error)
                }
            }
    }
    
    func downloadImage(from url: String) -> Observable<UIImage> {
        let provider = self.provider
        
        return provider.rx.request(.downloadImage(url: url))
            .asObservable()
            .flatMap { response -> Observable<UIImage> in
                guard let image = UIImage(data: response.data) else {
                    return .error(NSError(domain: "ImageError", code: -1, userInfo: [NSLocalizedDescriptionKey: "图片解析失败"]))
                }
                return .just(image)
            }
    }
    
    
    func requestStatusOnly(_ target: APIService, using provider: MoyaProvider<APIService>? = nil) -> Observable<BaseResponse<BaseStatusResponse>> {
        let usedProvider = provider ?? self.provider
        
        return usedProvider.rx.request(target)
            .filterSuccessfulStatusCodes()
            .mapObject(BaseResponse<BaseStatusResponse>.self)
            .asObservable()
            .flatMap { response -> Observable<BaseResponse<BaseStatusResponse>> in
                if response.isSuccess {
                    return .just(response)
                } else {
                    let error = NSError(domain: "APIError", code: response.code ?? -1, userInfo: [NSLocalizedDescriptionKey: response.message ?? "Unknown error"])
                    return .error(error)
                }
            }
    }
    
    func requestObject<T: Mappable>(_ target: APIService, type: T.Type) ->  Single<T> {
        return provider.rx.request(target)
            .filterSuccessfulStatusCodes()
            .mapObject(BaseResponse<T>.self)
            .flatMap { response ->  Single<T> in
                if response.isSuccess, let data = response.data {
                    return .just(data)
                } else {
                    let error = NSError(domain: "APIError", code: response.code ?? -1, userInfo: [NSLocalizedDescriptionKey: response.message ?? "Unknown error"])
                    return .error(error)
                }
            }
    }
    
    
    func requestObject<T: Mappable>(_ target: APIService, type: T.Type) -> Observable<T> {
        return authprovider.rx.request(target)
            .flatMap { response -> Single<Response> in
                if response.statusCode == 401 {
                    return self.refreshToken(TokenManager.shared.logintype).flatMap { _ in
                        return self.authprovider.rx.request(target)
                    }
                }
                return .just(response)
            }
            .filterSuccessfulStatusCodes()
            .mapObject(BaseResponse<T>.self)
            .asObservable()
            .flatMap { response -> Observable<T> in
                if response.isSuccess, let data = response.data {
                    return Observable.just(data)
                } else {
                    let error = NSError(domain: "APIError", code: response.code ?? -1, userInfo: [NSLocalizedDescriptionKey: response.message ?? "Unknown error"])
                    return Observable.error(error)
                }
            }
    }
    
    private func refreshToken(_ method: loginType) -> Single<Void> {
        // 模拟刷新请求，建议返回 Single
        let request : Single<Response>
        switch method {
        case .apple :
            request = authprovider.rx.request(.appleLogin(client: TokenManager.shared.appleUserIdentifier!, token: TokenManager.shared.appleToken!))
        default :
            request = authprovider.rx.request(.appleLogin(client: TokenManager.shared.appleUserIdentifier!, token: TokenManager.shared.appleToken!))
            
        }
        return request
            .mapObject(BaseResponse<TokenResponse>.self)
            .flatMap { response -> Single<Void> in
                if response.isSuccess, let token = response.data?.accessToken {
//                    guard let  token1 = token else {
//                        TokenManager.shared.updateToken(token)
//                        return .just(())
//                    }
                    TokenManager.shared.updateToken(TokenManager.shared.refreshToken)
                    return .just(())
                } else {
                    return .error(NSError(domain: "Auth", code: -1, userInfo: [NSLocalizedDescriptionKey: "Token刷新失败"]))
                }
            }
    }
    func requestPage<T: Mappable>(_ target: APIService, type: T.Type) -> Observable<[T]> {
        return provider.rx.request(target)
            .filterSuccessfulStatusCodes()
            .mapObject(BaseResponse<PageResponse<T>>.self)
            .asObservable()
            .flatMap { response -> Observable<[T]> in
                if response.isSuccess, let list = response.data?.list {
                    return Observable.just(list)
                } else {
                    return Observable.error(NSError(domain: "APIError", code: response.code ?? -1, userInfo: [NSLocalizedDescriptionKey: response.message ?? "未知错误"]))
                }
            }
    }
    
    
}
